#include "FourthModule.h"

FourthModule::FourthModule(NxScene* scene, NxVec3 position): m_object(scene), m_position(position), m_scene(scene)
{
}

FourthModule::~FourthModule(void)
{
}

NxActor* FourthModule::CreateFourthModule(void)
{
	//create the slope
	NxVec3 slopePosition = m_position + NxVec3(0, 20, 0);
	createSlope(slopePosition);

	//create the mini car
	NxVec3 carSize(0.5, 0.5, 0.5);
	NxVec3 carPosition = m_position + NxVec3(0, 23, 0);
	NxVec3 carFriction(0, 0, 1);
	m_object.CreateBox(carSize, carPosition, carFriction, 1);

	//create the windmill
	NxVec3 windmillPositiom = m_position + NxVec3 (65, -1, 0);
	createWindmill(windmillPositiom);

	//paperball plateform
	NxVec3 plateformSize(3, 0.5, 2);
	NxVec3 plateformPosition = m_position + NxVec3(60, (float)-5.1, 0);
	NxVec3 plateformFriction(1, 1, 1);
	NxVec3 plateformRotation(0, 0, 0);
	m_object.CreateKinematicBox(plateformSize, plateformPosition, plateformRotation, plateformFriction);

	//paperball
	NxVec3 paperBallPosition = m_position + NxVec3(61, -4, 0);
	float paperballRadius = 1;
	m_object.CreateSphere(paperBallPosition, paperballRadius, (float)10, 1, 1, 0);

	//bin
	NxVec3 binPosition = m_position + NxVec3((float)54.3, (float)-7.5, 0);
	createBin(binPosition);

	return 0;
}

void FourthModule::createSlope(const NxVec3& position)
{
	//first part
	NxVec3 positionPart1 = position;
	NxVec3 sizePart1(1, 0.5, 2);
	NxVec3 rotationPart1(0, 0, 0);
	NxVec3 frictionPart1(0, 0, 0);
	m_object.CreateKinematicBox(sizePart1, positionPart1, rotationPart1, frictionPart1);

	//slope part
	NxVec3 sizeSlop(20, 0.5, 2);
	NxVec3 positionSlope = position +NxVec3(10.5, (float)-17.1, 0);
	NxVec3 rotationSlope(0, 0, (float)-3.14/3);
	NxVec3 frictionSlope(0, 0, 0);
	m_object.CreateKinematicBox(sizeSlop, positionSlope, rotationSlope, frictionSlope);

	//U part
	NxVec3 sizeU1(10, 0.5, 2);
	NxVec3 positionU1 = position +NxVec3(12, -17, 0);
	NxVec3 rotationU1(0, 0, (float)-3.14/4);
	NxVec3 frictionU1(0, 0, 0);
	m_object.CreateKinematicBox(sizeU1, positionU1, rotationU1, frictionU1);

	NxVec3 sizeU2(10, 0.5, 2);
	NxVec3 positionU2 = position +NxVec3(20, -22, 0);
	NxVec3 rotationU2(0, 0, (float)-3.14/10);
	NxVec3 frictionU2(0, 0, 0);
	m_object.CreateKinematicBox(sizeU2, positionU2, rotationU2, frictionU2);

	NxVec3 sizeU3(10, 0.5, 2);
	NxVec3 positionU3 = position +NxVec3(35, -25, 0);
	NxVec3 rotationU3(0, 0, 0);
	NxVec3 frictionU3(0, 0, 0);
	m_object.CreateKinematicBox(sizeU3, positionU3, rotationU3, frictionU3);

	NxVec3 sizeU4(10, 0.5, 2);
	NxVec3 positionU4 = position +NxVec3(45, -22, 0);
	NxVec3 rotationU4(0, 0, (float)3.14/10);
	NxVec3 frictionU4(0, 0, 0);
	m_object.CreateKinematicBox(sizeU4, positionU4, rotationU4, frictionU4);
}

void FourthModule::createWindmill(const NxVec3& position)
{
	//the actor descriptor for the feet
	NxActorDesc actorWindmill;

	const int numberOfArm = 5;
	const int radius = 2;

	//the shape descriptor for arm of the windmill
	NxBoxShapeDesc armDesc[5];
	for(int i=0; i<numberOfArm; i++)
	{
		const float armMass = (float)0.1;
		const NxVec3 armDimensions(2, (float)0.2, 2);
		armDesc[i].dimensions.set(armDimensions);
		
		float angle = (float)(2*3.14/numberOfArm*i);
		armDesc[i].localPose.t = NxVec3(cos(angle)*radius, sin(angle)*radius, 0);
		armDesc[i].localPose.M.rotZ(angle);
		armDesc[i].mass = armMass;

		actorWindmill.shapes.push_back(&armDesc[i]);
	
	}
	NxBodyDesc body;
	actorWindmill.body = &body;
	actorWindmill.density = 10;
	actorWindmill.globalPose.t = position;
	actorWindmill.globalPose.M.rotZ((float)3.14/8);
	//add the actor to the scene
	NxActor* actorWm = m_scene->createActor(actorWindmill);

	//create the joint
	NxRevoluteJointDesc joint;
	joint.actor[1] = 0;
	joint.actor[0] = actorWm;

	NxVec3 anchor = position;

	joint.setGlobalAnchor(anchor);
	joint.setGlobalAxis(NxVec3(0, 0, 1));

	joint.jointFlags =NX_JF_COLLISION_ENABLED;

	joint.projectionMode = NX_JPM_POINT_MINDIST;
	joint.projectionDistance = 0;
	joint.projectionAngle = (float)0.0872;

	NxJoint* newJoint = m_scene->createJoint(joint);
}
void FourthModule::createBin(const NxVec3& position)
{
	NxActorDesc binDesc;

	NxBoxShapeDesc binSide[4];
	const int xSide = 2;
	for(int i=0; i<4; i++)
	{
		
		binSide[i].dimensions.set((float)xSide, (float)1.9, (float)0.2);
		binSide[i].localPose.M.rotY((float)3.14/2*i);

		/*binSide[i].localPose.t = NxVec3(xSide/2, 0, xSide/2);

		if(i==0 || i==3)
		{
			binSide[i].localPose.t.z *=-1;
			binSide[i].localPose.t.x =0;
		}

		if(i<2)
		{
			binSide[i].localPose.t.x *=-1;
			binSide[i].localPose.t.z =0;
		}*/

		if(i == 0)
		{
			binSide[i].localPose.t = NxVec3(0, 0, (float)xSide);
		}
		else if(i ==1)
		{
			binSide[i].localPose.t = NxVec3((float)xSide, 0, 0);
		}
		else if (i ==2)
		{
			binSide[i].localPose.t = NxVec3(0, 0, (float)-xSide);
		}
		else
		{
			binSide[i].localPose.t = NxVec3((float)-xSide, 0, 0);
		}
		binDesc.shapes.push_back(&binSide[i]);
	}

	NxBoxShapeDesc back;
	back.dimensions.set((float)xSide, (float)0.2, (float)xSide);
	back.localPose.t = NxVec3(0, (float)-2.2, 0);
	binDesc.shapes.push_back(&back);

	binDesc.body = 0;
	binDesc.density = 10;
	binDesc.globalPose.t = position;

	m_scene->createActor(binDesc);
}